/*
 * heurAlgV.cpp
 *
 *  Created on: 30-09-2011
 *      Author: pawel
 */
#include"heurAlgV.h"
#include"../seqFeederList.h"
#include"../smart2DArray.h"

#include<stdio.h>

heurAlgV::heurAlgV(const optAlgThreadParam &optAlgParam,size_t heurThreads,size_t optThreads)
:optAlgThParam(optAlgParam),heurThreads(heurThreads),optThreads(optThreads),listFeederPtr(new seqFeederList),
mainSeqFeederPtr(optAlgParam.seqFeederPtr)
{
optAlgThParam.seqFeederPtr = listFeederPtr.get();
}
/*
 * Static
 */

void* heurAlgV::heurThreadEntry(void* arg){
	heurAlgV *heurAlgPtr;
	heurAlgPtr = (heurAlgV*)arg;
	heurAlgPtr->runThread();
	return 0;
}
void heurAlgV::startThreads(heurAlgV *heurAlg){
	try{
		pthread_t *optAlgThreads;
		pthread_t *heurAlgThreads;
		smart2DArray<pthread_t> smartoptAlgThreads(1,heurAlg->optThreads);
		optAlgThreads = (smartoptAlgThreads.getPtr())[0];
		smart2DArray<pthread_t> smartheurAlgThreads(1,heurAlg->heurThreads);
		heurAlgThreads = (smartheurAlgThreads.getPtr())[0];
	/*
	 * heur threads
	 */
		for(size_t i=0;i<heurAlg->heurThreads;i++){
			pthread_create( &heurAlgThreads[i], NULL, heurAlgV::heurThreadEntry, (void*)(heurAlg));
		}
	/*
	 * opt Alg threads
	 */
		for(size_t i=0;i<heurAlg->optThreads;i++){
			pthread_create( &optAlgThreads[i], NULL, optAlgThread, (void*)(&(heurAlg->optAlgThParam)));
		}
		/*
		 * Join threads
		 */
		for(size_t i=0;i<heurAlg->heurThreads;i++){
			pthread_join( heurAlgThreads[i], NULL);
		}
		pthread_mutex_lock( heurAlg->listFeederPtr.get()->getMutex() );
		heurAlg->listFeederPtr.get()->endProduction();
		pthread_cond_broadcast(heurAlg->listFeederPtr.get()->getNotEmpty());
		pthread_mutex_unlock( heurAlg->listFeederPtr.get()->getMutex() );
		for(size_t i=0;i<heurAlg->optThreads;i++){
			pthread_join( optAlgThreads[i], NULL);
		}


	}catch(std::exception& e){
		throw;
	}

}
heurAlgV::~heurAlgV(){

}



